package com.bc.ljn.catwars;


import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import java.util.Random;
import java.util.Vector;

/**
 * Created by ljn on 2014/12/23.
 */
public class GameView extends SurfaceView implements SurfaceHolder.Callback, Runnable {
    // 屏幕的宽高
    public static int screenW;
    public static int screenH;
    private SurfaceHolder holder;
    private Canvas canvas;
    private Paint paint;
    private Thread thread; // 刷新线程
    private boolean flag; // 线程消亡的标识位

    public static final int GAME_MENU = 0; // 游戏菜单
    public static final int GAMEING = 1; // 游戏中
    public static final int GAME_WIN = 2; // 游戏胜利
    public static final int GAME_LOST = 3; // 游戏失败
    public static final int GAME_PAUSE = -1; // 游戏菜单
    // 当前游戏状态（默认初始为菜单）
    public static int gameState = GAME_MENU;

    // 声明一个 Resources 实例便于加载图片
    private Resources res = this.getResources();
    // 声明游戏需要用到的图片资源
    private Bitmap bmpBackGround; // 游戏背景
    private Bitmap bmpBoom; //爆炸效果
    private Bitmap bmpButton; // 游戏开始按钮
    private Bitmap bmpButtonPressed; // 游戏开始按钮被点击
    private Bitmap bmpEnemyDog; // 敌人狗
    private Bitmap bmpEnemy2; // 敌人2
    private Bitmap bmpEnemyBoss;
    private Bitmap bmpGameWin; // 游戏胜利背景
    private Bitmap bmpGameLost; // 游戏失败背景
    private Bitmap bmpPlayerCat; // 主角机
    private Bitmap bmpPlayerHP; //主角机血量
    private Bitmap bmpMenu; //菜单背景
    private Bitmap bmpBullet; //我方子弹
    public static Bitmap bmpEnemyDogBullet; // 敌人狗子弹
    public Bitmap bmpScore;

    // 声明一个菜单对象
    private GameMenu gameMenu;
    private GameBg backGround;
    private Player player;

    // 声明一个敌机容器
    private Vector<Enemy> vcEnemy;
    // 每次生成敌机的时间（毫秒）
    private int createEnemyTime = 50;
    private int count; //计数器
    //敌人数组，1和2表示敌人种类，-1表示Boss
    //二位数组的每一维都表示一组怪物
    private int enemyArray[][] = {{1, 2}, {1, 1}, {2, 2}, {1, 2}, {2, 1}, {1, 2}, {2, 2}, {1, 2},
            {1, 1}, {2, 2}, {1, 2}, {2, 1}, {1, 2}, {2, 2}, {1, 2}, {2, 2}, {1, 2}, {-1}};
    //当前取出一组数组的下标
    private int enemyArrayIndex;
    //是否出现BOSS标识位
    private boolean isBoss;
    //随即库， 为创建的敌机赋予随机坐标
    private Random random;

    //敌机子弹容器
    private Vector<Bullet> vcBullet = new Vector<Bullet>();
    //添加子弹的计数器
    private int countEnemyBullet;
    //主角的子弹容器
    private Vector<Bullet> vcBulletPlayer = new Vector<Bullet>();
    //添加子弹的计数器
    private int countPlayerBullet;

    //爆炸效果容器
    private Vector<Boom> vcBoom = new Vector<Boom>();

    private Boss boss;
    public static Vector<Bullet> vcBulletBoss = new Vector<Bullet>();

    private Score score;


    public GameView(Context context) {
        super(context);
        holder = this.getHolder();
        holder.addCallback(this);
        paint = new Paint();
    }

    //初始函数
    private void initGame() {
        // 放置游戏切入后台重新进入游戏时，游戏被重置！
        // 当游戏处于菜单时，才会重置游戏
        if (gameState == GAME_MENU) {
            // 加载游戏资源
            bmpBackGround = BitmapFactory.decodeResource(res, R.drawable.background);
            bmpBoom = BitmapFactory.decodeResource(res, R.drawable.boom);
            bmpButton = BitmapFactory.decodeResource(res, R.drawable.button);
            bmpButtonPressed = BitmapFactory.decodeResource(res, R.drawable.button_pressed);
            bmpEnemyDog = BitmapFactory.decodeResource(res, R.drawable.dog);
            bmpEnemy2 = BitmapFactory.decodeResource(res, R.drawable.enemy2);
            bmpEnemyBoss = BitmapFactory.decodeResource(res, R.drawable.boss);
            bmpGameWin = BitmapFactory.decodeResource(res, R.drawable.win);
            bmpGameLost = BitmapFactory.decodeResource(res, R.drawable.lost);
            bmpPlayerCat = BitmapFactory.decodeResource(res, R.drawable.cat);
            bmpPlayerHP = BitmapFactory.decodeResource(res, R.drawable.heart);
            bmpMenu = BitmapFactory.decodeResource(res, R.drawable.start);
            bmpEnemyDogBullet = BitmapFactory.decodeResource(res, R.drawable.dog_weapon);
            bmpBullet = BitmapFactory.decodeResource(res, R.drawable.cat_weapon);
            bmpScore = BitmapFactory.decodeResource(res, R.drawable.numbers);

            //菜单类实例
            gameMenu = new GameMenu(bmpMenu, bmpButton, bmpButtonPressed);
            backGround = new GameBg(bmpBackGround);
            player = new Player(bmpPlayerCat, bmpPlayerHP);

            //实例敌机容器
            vcEnemy = new Vector<Enemy>();
            random = new Random();

            boss = new Boss(bmpEnemyBoss);
            vcBulletBoss = new Vector<Bullet>();

            score = new Score(bmpScore);
        }
    }


    // 绘制函数
    public void myDraw() {
        try {
            canvas = holder.lockCanvas();
            if (canvas != null) {

                //绘制函数根据游戏状态不同绘制不同函数
                switch (gameState) {
                    case GAME_MENU:
                        // 菜单的绘图函数
                        gameMenu.draw(canvas, paint);
                        break;
                    case GAMEING:
                        //绘制背景
                        backGround.draw(canvas, paint);
                        //绘制主角
                        player.draw(canvas, paint);

                        if (isBoss == false) {
                            //敌机绘制
                            for (int i = 0; i < vcEnemy.size(); i++) {
                                vcEnemy.elementAt(i).draw(canvas, paint);

                            }
                            //敌机子弹绘制
                            for (int i = 0; i < vcBullet.size(); i++) {
                                vcBullet.elementAt(i).draw(canvas, paint);
                            }
                        } else {
                            //boss绘制
                            boss.draw(canvas, paint);
                            //Boss 子弹绘制
                            for (int i = 0; i < vcBulletBoss.size(); i++) {
                                vcBulletBoss.elementAt(i).draw(canvas, paint);
                            }
                        }
                        //处理主角子弹绘制
                        for (int i = 0; i < vcBulletPlayer.size(); i++) {
                            vcBulletPlayer.elementAt(i).draw(canvas, paint);
                        }
                        //爆炸效果绘制
                        for (int i = 0; i < vcBoom.size(); i++) {
                            vcBoom.elementAt(i).draw(canvas, paint);
                        }

                        score.draw(canvas, paint);
                        break;
                    case GAME_PAUSE:

                        break;
                    case GAME_WIN:
                        canvas.drawBitmap(bmpGameWin, 0, 0, paint);
                        break;
                    case GAME_LOST:
                        canvas.drawBitmap(bmpGameLost, 0, 0, paint);
                        break;
                }
            }
        } catch (Exception e) {
            // TODO: handle exception
        } finally {
            if (canvas != null)
                holder.unlockCanvasAndPost(canvas);
        }
    }

    // 逻辑函数
    private void logic() {

        // 根据不同游戏状态处理逻辑函数
        switch (gameState) {
            case GAME_MENU:
                break;
            case GAMEING:
                backGround.logic();
                player.logic();

                if (isBoss == false) {
                    //敌机逻辑
                    for (int i = 0; i < vcEnemy.size(); i++) {
                        Enemy en = vcEnemy.elementAt(i);
                        //如果已经死亡，则从容器中删除
                        if (en.isDead) {
                            vcEnemy.removeElementAt(i);
                        } else {
                            en.logic();
                        }
                    }
                    //生成敌机
                    count++;
                    if (count % createEnemyTime == 0) {
                        for (int i = 0; i < enemyArray[enemyArrayIndex].length; i++) {
                            //dog
                            if (enemyArray[enemyArrayIndex][i] == 1) {
                                int x = random.nextInt(screenW - 100) + 50;
                                vcEnemy.addElement(new Enemy(bmpEnemyDog, 1, x, -50));
                            } else if (enemyArray[enemyArrayIndex][i] == 2) {
                                int y = random.nextInt(20);
                                vcEnemy.addElement(new Enemy(bmpEnemy2, 2, 50, y));
                            }
                        }
                        //这里判断下一组是否为boss
                        if (enemyArrayIndex == enemyArray.length - 1) {
                            isBoss = true;
                        } else {
                            enemyArrayIndex++;
                        }
                    }

                    //每2秒增加一个敌机子弹
                    countEnemyBullet++;
                    if (countEnemyBullet % 40 == 0) {
                        for (int i = 0; i < vcEnemy.size(); i++) {
                            Enemy en = vcEnemy.elementAt(i);
                            //不同类型敌机不同的子弹运行轨迹
                            int bulletType = 0;
                            switch (en.type) {
                                //dog
                                case Enemy.TYPE_DOG:
                                    bulletType = Bullet.BULLET_DOG;
                                    break;
                                case Enemy.TYPE_2:
                                    bulletType = Bullet.BULLET_DOG;
                                    break;
                            }
                            vcBullet.add(new Bullet(bmpEnemyDogBullet, en.x + 10, en.y + 20, bulletType));
                        }
                    }
                    //处理敌机子弹逻辑
                    for (int i = 0; i < vcBullet.size(); i++) {
                        Bullet b = vcBullet.elementAt(i);
                        if (b.isDead) {
                            vcBullet.removeElement(b);
                        } else {
                            b.logic();
                        }
                    }
                } else {
                    //boss逻辑
                    //boss相关逻辑
                    //每0.5秒增加一个主角子弹
                    boss.logic();
                    if (countPlayerBullet % 10 == 0) {
                        //Boss的没发疯之前的普通子弹
                        vcBulletBoss.add(new Bullet(bmpEnemyDogBullet, boss.x + 35, boss.y, Bullet.BULLET_BOSS));
                    }
                    //Boss子弹逻辑
                    for (int i = 0; i < vcBulletBoss.size(); i++) {
                        Bullet b = vcBulletBoss.elementAt(i);
                        if (b.isDead) {
                            vcBulletBoss.removeElement(b);
                        } else {
                            b.logic();
                        }
                    }
                    //Boss子弹与主角相碰
                    for (int i = 0; i < vcBulletBoss.size(); i++) {
                        if (player.isCollisionWith(vcBulletBoss.elementAt(i))) {
                            player.setPlayerHP(player.getPlayerHP() - 1);
                            if (player.getPlayerHP() <= 1) {
                                gameState = GAME_LOST;
                            }
                        }
                    }
                    //Boss被主角击中，产生爆炸效果
                    for (int i = 0; i < vcBulletPlayer.size(); i++) {
                        Bullet b = vcBulletPlayer.elementAt(i);
                        if (boss.isCollisionWith(b)) {
                            if (boss.hp <= 0) {
                                gameState = GAME_WIN;
                            } else {
                                b.isDead = true;
                                boss.setHP(boss.hp - 1);
                                vcBoom.add(new Boom(bmpBoom, boss.x + 25, boss.y + 30, 7));
                                vcBoom.add(new Boom(bmpBoom, boss.x + 35, boss.y + 40, 7));
                                vcBoom.add(new Boom(bmpBoom, boss.x + 45, boss.y + 50, 7));
                            }
                        }
                    }
                }
                //每0.1秒增加一个主角子弹
                countPlayerBullet++;
                if (countPlayerBullet % 2 == 0) {
                    vcBulletPlayer.add(new Bullet(bmpBullet, player.x + 15, player.y - 20, Bullet.BULLET_PLAYER));
                }
                //处理敌机子弹逻辑
                for (int i = 0; i < vcBulletPlayer.size(); i++) {
                    Bullet b = vcBulletPlayer.elementAt(i);
                    if (b.isDead) {
                        vcBulletPlayer.removeElement(b);
                    } else {
                        b.logic();
                    }
                }

                //处理敌机与主角的碰撞
                for (int i = 0; i < vcEnemy.size(); i++) {
                    if (player.isCollsionWith(vcEnemy.elementAt(i))) {
                        //发生碰撞
                        player.setPlayerHP(player.getPlayerHP() - 1);
                    }
                }
                //处理敌机子弹与主角的碰撞
                for (int i = 0; i < vcBullet.size(); i++) {
                    if (player.isCollisionWith(vcBullet.elementAt(i))) {
                        player.setPlayerHP(player.getPlayerHP() - 1);
                        if (player.getPlayerHP() <= -1) {
                            gameState = GAME_LOST;
                        }
                    }
                }
                //处理主角子弹与敌机碰撞
                for (int i = 0; i < vcBulletPlayer.size(); i++) {
                    //取出主角子弹容器的每个元素
                    Bullet blPlayer = vcBulletPlayer.elementAt(i);
                    for (int j = 0; j < vcEnemy.size(); j++) {
                        //添加爆炸效果
                        //取出敌机容器的每个元与主角子弹遍历
                        if (vcEnemy.elementAt(j).isCollisionWith(blPlayer)) {
                            //添加爆炸效果
                            vcBoom.add(new Boom(bmpBoom, vcEnemy.elementAt(j).x, vcEnemy.elementAt(j).y, 7));
                        }
                    }
                }
                //爆炸效果逻辑
                for (int i = 0; i < vcBoom.size(); i++) {
                    Boom boom = vcBoom.elementAt(i);
                    if (boom.playEnd) {
                        //播放完毕的从容器中删除
                        vcBoom.removeElementAt(i);
                    } else {
                        vcBoom.elementAt(i).logic();
                    }
                }
                score.logic();

                break;
            case GAME_PAUSE:
                break;
            case GAME_WIN:
                break;
            case GAME_LOST:
                break;
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // 根据不同游戏状态处理监听事件
        switch (gameState) {
            case GAME_MENU:
                //菜单的触屏事件处理
                gameMenu.onTouchEvent(event);
                break;
            case GAMEING:
                player.onTouchEvent(event);
                break;
            case GAME_PAUSE:
                break;
            case GAME_WIN:
                break;
            case GAME_LOST:
                break;
        }
        return true;
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        screenW = this.getWidth();
        screenH = this.getHeight();
        flag = true;
        initGame();

        thread = new Thread(this);
        thread.start();
    }

    @Override
    public void run() {
        while (flag) {
            long start = System.currentTimeMillis();
            myDraw();
            logic();
            long end = System.currentTimeMillis();
            try {
                if (end - start < 50) {
                    Thread.sleep(50 - (end - start));
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        flag = false;
    }
}
